/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c), 2003-2011,  Jin Chen and Alan M. MacEachren, GeoVISTA Center, Penn State University
 * Licensed under Simplified BSD License
 *
 *  
 * @Original Author: jin Chen
 * @date: Sep 8, 2004$
 * @version: 1.0
 */
package edu.psu.geovista.app.dataloader.v1.components;

import edu.psu.geovista.data.model.BasicMetadataModel;
import edu.psu.geovista.data.model.MetadataModel;

import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;

public abstract class MetaDataTable implements edu.psu.geovista.data.model.MetaData {
   // protected  BasicMetatdataModel datamodel=null;
    protected Set <MetadataModel>  datamodels=new HashSet<MetadataModel>(1);//to support merge data (Pcp, Time Series) and therefore meta data. Since  data schema of meta data usually are different, thus need store them seperately.
    /**
        *  Store individual value:
        *      - if projected
        *      - column name of the observation name column
        *
        */
    protected Hashtable metaData=new Hashtable(); // 
    /**
     * Implement based on application's specification
     */
    protected abstract void process() throws UnsupportedOperationException;
    protected void reset(){
        this.metaData.clear();
    }
    public void setMetaData(Object key,Object value) {
        metaData.put(key,value);
    }
    /**
     *  
     *  
     *
     *
     * @param keyColumnName      the name of column in this meta data, whose elements will serve as key in the mapping
     * @param valueColumnName    the name of column in this meta data, whose elements will serve as value in the mapping
     * @return
     */
    public Hashtable getMappingForColumn(String keyColumnName,String valueColumnName){
        Hashtable map=new Hashtable();
        for (Iterator iterator = datamodels.iterator(); iterator.hasNext();) {
            MetadataModel datamodel = (MetadataModel) iterator.next();


            // 
            if(datamodel!=null){
                int indexKey = datamodel.getColumnIndexByNameIgnoreCase(keyColumnName);
                int indexVal = datamodel.getColumnIndexByNameIgnoreCase(valueColumnName);
                if(indexKey>=0&&indexVal>=0){
                    Object[] keyColumn = datamodel.getColumnAsArray(indexKey);
                    Object[] valColumn = datamodel.getColumnAsArray(indexVal);
                    for (int i=0;i<keyColumn.length ;i++){

                        Object key = keyColumn[i];

                        Object value = valColumn[i];
                        if(key!=null&&value!=null)
                            map.put(key,value);
                        else{
                            //todo a bug?
                        }
                    }
                }
            }
        }
        return map;
    }
    public Object getMetaData(Object key){
        return metaData.get(key);
    }

    public Set<MetadataModel> getModel() {
        return datamodels;
    }

    /**
     * only keep one datamodel
     * @param datamodel
     */
    public void setModel(BasicMetadataModel datamodel)  {
        //datamodel can be null when clone() is invoked
        //this.datamodel = datamodel;
       this.datamodels.clear();
        datamodels.add(datamodel);
    }
    public void addDatamodel(MetadataModel datamodel)  {
         datamodels.add(datamodel);
    }
    public void addDatamodel(Set <MetadataModel> datamodels)  {
         this.datamodels.addAll(datamodels);
    }
    public abstract Object clone() ;

}
